package org.esk.dablog.model;

import org.hibernate.annotations.Cascade;

import javax.persistence.*;
import java.util.Date;
import java.util.Set;
import java.util.HashSet;

/**
 * This class represents basic "ENTRY" entity.
 *
 * States should be assigned by the following agreement:
 *  State < 1000 = entry will be visible on a site;
 *  State > 1000 = entry should be visible by administrators only
 *
 * User: jc
 * Date: 22.11.2006
 * Time: 10:33:08
 * $Id:$
 *
 * @hibernate.class
 *   table="ENTRIES"
 *   lazy="true"
 *   discriminator-value="0"
 * 
 * @hibernate.discriminator
 *   column="ENTRY_TYPE"
 *   type="integer"
 */
@Entity
@Table(name = "ENTRIES")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "ENTRY_TYPE", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue(value="0")
public class Entry {

    private long id;
    private int entryType;
    private String header;
    private String text;
    private Date date;
    private String anonymousName;
    private String ip;
    private int state;
    private Entry parent;

    private boolean anonymous;

    private boolean allowAnonymousComments;

    private Author author;

    private Set<Picture> pictures;

    private Set<Comment> comments;


    /**
     * is entry active 
     * @return
     */
    @Transient
    public boolean isActive() {
        return true;
    }


    /**
     * adds a comment to the entry
     * @param c
     */
    public void addComment(Comment c) {
        if(comments == null) {
            comments = new HashSet<Comment>();
        }
        comments.add(c);
        c.setEntry(this);
    }

    /**
     * adds a picture to the entry
     * @param p
     */
    public void addPicture(Picture p) {
        if(pictures == null) {
            pictures = new HashSet();
        }
        pictures.add(p);
        p.setEntry(this);        
    }

    /**
     * @hibernate.id
     *   column="ID"
     *   generator-class="native"
     * @hibernate.generator-param
     *   name="sequence"
     *   value="SEQ_ENTRIES"
     * @return
     */
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ENTRIES")
    @SequenceGenerator(name = "SEQ_ENTRIES", sequenceName = "seq_entries")
    @Column(name = "ID")
    public long getId() {
        return id;
    }

    /**
     * @hibernate.property
     *   column="ENTRY_TYPE"
     *   insert="false"
     *   update="false"
     * @return
     */
    @Column(name="ENTRY_TYPE", insertable=false, updatable=false)
    public int getEntryType() {
        return entryType;
    }

    /**
     * @hibernate.property
     *   column="ENTRY_HEADER"
     *   length="1024"
     * @return
     */
    @Column(name="ENTRY_HEADER", length=1024)
    public String getHeader() {
        return header;
    }

    /**
     * @hibernate.property
     *   column="ENTRY_TEXT"
     *   length="8192"
     * @return
     */
    @Column(name="ENTRY_TEXT", length=8192)
    public String getText() {
        return text;
    }

    /**
     * @hibernate.property
     *   column="ENTRY_DATE"
     * @return
     */
    @Column(name="ENTRY_DATE")
    public Date getDate() {
        return date;
    }

    /**
     * @hibernate.property
     *   column="ANONYMOUS_NAME"
     * @return
     */
    @Column(name="ANONYMOUS_NAME")
    public String getAnonymousName() {
        return anonymousName;
    }

    /**
     * @hibernate.property
     *   column="IP_ADDRESS"
     * @return
     */
    @Column(name="IP_ADDRESS")
    public String getIp() {
        return ip;
    }

    /**
     * @hibernate.property
     *   column="IS_ANONYMOUS"
     * @return
     */
    @Column(name="IS_ANONYMOUS")
    public boolean isAnonymous() {
        return anonymous;
    }

    /**
     * @hibernate.property
     *   column="IS_ALLOW_ANONYMOUS_COMMENTS"
     * @return
     */
    @Column(name="IS_ALLOW_ANONYMOUS_COMMENTS")
    public boolean isAllowAnonymousComments() {
        return allowAnonymousComments;
    }


    /**
     * @hibernate.many-to-one
     *   column="AUTHOR_ID"
     * @return
     */
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "AUTHOR_ID")    
    public Author getAuthor() {
        return author;
    }


    /**
     * @hibernate.set
     *   lazy="true"
     *   inverse="true"
     *   cascade="all-delete-orphan"
     *   order-by="ID"
     * @hibernate.one-to-many
     *   class="org.esk.dablog.model.Picture"
     * @hibernate.key
     *   column="ENTRY_ID"
     * @return
     */
    @OneToMany(mappedBy="entry", cascade=CascadeType.ALL)
    @JoinColumn(name="ENTRY_ID")
    @Cascade(value={org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    public Set<Picture> getPictures() {
        return pictures;
    }

    /**
     * @hibernate.set
     *   lazy="false"
     *   inverse="true"
     *   cascade="all-delete-orphan"
     *   order-by="ID"
     * @hibernate.one-to-many
     *   class="org.esk.dablog.model.Comment"
     * @hibernate.key
     *   column="ENTRY_ID"
     * @return
     */
    @OneToMany(mappedBy="entry", cascade=CascadeType.ALL)
    @JoinColumn(name="ENTRY_ID")
    @Cascade(value={org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    public Set<Comment> getComments() {
        return comments;
    }

    /**
     * @hibernate.property
     *   column="STATE"
     * @return
     */
    @Column(name="STATE")
    public int getState() {
        return state;
    }


    /**
     * @hibernate.many-to-one
     *   column="PARENT_ENTRY_ID"
     *   not-null="false"
     * @return
     */
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "PARENT_ENTRY_ID")    
    public Entry getParent() {
        return parent;
    }

    public void setParent(Entry parent) {
        this.parent = parent;
    }

    public void setState(int state) {
        this.state = state;
    }

    public void setComments(Set<Comment> comments) {
        this.comments = comments;
    }

    public void setPictures(Set<Picture> pictures) {
        this.pictures = pictures;
    }

    public void setId(long id) {
        this.id = id;
    }

    public void setEntryType(int entryType) {
        this.entryType = entryType;
    }

    public void setHeader(String header) {
        this.header = header;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public void setAnonymousName(String anonymousName) {
        this.anonymousName = anonymousName;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public void setAnonymous(boolean anonymous) {
        this.anonymous = anonymous;
    }

    public void setAllowAnonymousComments(boolean allowAnonymousComments) {
        this.allowAnonymousComments = allowAnonymousComments;
    }

    public void setAuthor(Author author) {
        this.author = author;
    }
}
